<script>
	import {
		getGoodsList,
		getShopBgList
	} from "@/api/mall";
	import {
		getArticleDetail,
		useArticleApi
	} from "@/api/homePage";
	import config from "../config";
	import HzSafeArea from "@/components/layout/hz/hz-safe-area.vue";

	export default {
		name: "details",
		components: {
			HzSafeArea,
		},
		data() {
			return {
				module: {
					boatGuide: {
						type: "article",
						title: "乘船指南",
						id: "boatGuide",
						data: null,
						loading: true
					},
					attractions: {
						type: "merchants",
						title: "热门玩乐",
						id: "attractions",
						data: [],
						loading: true
					},
					gourmet: {
						type: "merchants",
						title: "必打卡美食",
						id: "gourmet",
						data: [],
						loading: true
					},
					accommodation: {
						type: "merchants",
						title: "岛上住宿",
						id: "accommodation",
						data: [],
						loading: true
					},
					// products: {
					// 	type: "commodity",
					// 	title: "推荐产品",
					// 	id: "products",
					// 	data: [],
					// 	loading: true
					// }
				},
				regionalId: null,
				playImgId: null,
				hotelImgId: null,
				restaurantImgId: null,
				scenicSpot: null,
				bannerImages: [],
				bannerTitle: "",
				scrollIntoView: "",
				basicInfo: {
					name: "",
					address: "",
					businessHours: ""
				},
				pageLoading: true,
				currentTab: "boatGuide",
				showBackToTop: false,
				scrollTop: 0,
				isNavSticky: false,
				scrollTopValue: 0,
				topElementId: "page-top",
				articleDetail: null,
				hotelDetail: null,
				restaurantDetail: null
			}
		},
		onLoad(options) {
			uni.showLoading({
				title: '加载中...',
				mask: true
			});

			if (options && options.id) {
				this.scenicSpot = options.id;
				this.regionalId = config[options.id].regionalId;
				this.playImgId = config[options.id].playImgId;
				this.restaurantImgId = config[options.id].restaurantImgId;
				this.hotelImgId = config[options.id].hotelImgId;

				// 设置页面标题
				uni.setNavigationBarTitle({
					title: '景区详情'
				});

				this.init();
			} else {
				uni.showToast({
					title: '参数错误',
					icon: 'none'
				});

				setTimeout(() => {
					uni.navigateBack();
				}, 1500);
			}
		},
		onReady() {
			// 页面加载后，设置第一个模块为活动模块
			this.currentTab = "boatGuide";
		},
		methods: {
			async init() {
				// 并行加载各个模块数据
				const promises = [
					this.setupBannerImages(),
					this.loadBoatGuide(),
					this.loadAttractions(),
					this.getHotArticle(),
					this.getHotel(),
					this.getRestaurant(),
					this.loadGourmet(),
					this.loadAccommodation(),
					this.loadProducts()
				];

				try {
					await Promise.all(promises);
					this.pageLoading = false;
					uni.hideLoading();
				} catch (error) {
					console.error('加载数据失败', error);
					uni.hideLoading();
					uni.showToast({
						title: '加载失败',
						icon: 'none'
					});
				}
			},


			// 加载乘船指南
			async loadBoatGuide() {
				try {
					const res = await this.getTheArticle();

					if (res && res.Data && res.Data.length > 0) {
						const res2 = await getArticleDetail({
							Id: res.Data[0].Id
						})

						console.log(res2.Data)
						this.module.boatGuide.data = res2.Data;
					}



				} catch (error) {
					console.error('加载乘船指南失败', error);
				} finally {
					setTimeout(() => {
						this.module.boatGuide.loading = false;
					}, 300);
				}
			},

			// 加载热门景点
			async loadAttractions() {
				try {
					const res = await this.getTheMerchant({
						Index: 1,
						Size: 10,
						AreaId: this.regionalId,
						IsHot: 1,
						BusinessClassify: 2 // 热门景点对应BusinessClassify为2

					});
					if (res && res.Data) {
						this.module.attractions.data = res.Data;

						// 设置轮播图数据
						// this.setupBannerImages();
					}
				} catch (error) {
					console.error('加载热门景点失败', error);
				} finally {
					setTimeout(() => {
						this.module.attractions.loading = false;
					}, 600);
				}
			},

			// 加载必打卡美食
			async loadGourmet() {
				try {
					const res = await this.getTheMerchant({
						Index: 1,
						Size: 10,
						AreaId: this.regionalId,
						IsHot: 1,
						BusinessClassify: 3 // 打卡美食对应BusinessClassify为3
					});
					if (res && res.Data) {
						this.module.gourmet.data = res.Data;
					}
				} catch (error) {
					console.error('加载必打卡美食失败', error);
				} finally {
					setTimeout(() => {
						this.module.gourmet.loading = false;
					}, 900);
				}
			},
			async getHotArticle() {
				try {

					const {
						Data
					} = await getArticleDetail({
						Id: this.playImgId
					});
					console.log("热门玩乐 articleDetail =>", Data)
					this.articleDetail = Data

				} catch (e) {
					this.articleDetail = null
					console.log(e)
				}
			},
			async getHotel() {
				try {

					const {
						Data
					} = await getArticleDetail({
						Id: this.hotelImgId
					});
					console.log("住宿图文 hotelDetail =>", Data)
					this.hotelDetail = Data

				} catch (e) {
					this.hotelDetail = null
					console.log(e)
				}
			},

			async getRestaurant() {
				try {

					const {
						Data
					} = await getArticleDetail({
						Id: this.restaurantImgId
					});
					console.log("美食图文 restaurantDetail =>", Data)
					this.restaurantDetail = Data

				} catch (e) {
					this.restaurantDetail = null
					console.log(e)
				}
			},


			// 加载岛上住宿
			async loadAccommodation() {
				try {
					const res = await this.getTheMerchant({
						Index: 1,
						Size: 10,
						AreaId: this.regionalId,
						IsHot: 1,
						BusinessClassify: 4 // 住宿对应BusinessClassify为4
					});
					if (res && res.Data) {
						this.module.accommodation.data = res.Data;
					}
				} catch (error) {
					console.error('加载岛上住宿失败', error);
				} finally {
					setTimeout(() => {
						this.module.accommodation.loading = false;
					}, 1200);
				}
			},

			// 加载推荐产品
			async loadProducts() {
				try {
					const res = await this.getRecommendedProducts();
					if (res && res.Data) {
						this.module.products.data = res.Data;
						console.log("++++++++ 推荐产品 +++++++", res.Data);
					}
				} catch (error) {
					console.error('加载推荐产品失败', error);
				} finally {
					setTimeout(() => {
						this.module.products.loading = false;
					}, 1500);
				}
			},

			// 设置轮播图数据
			async setupBannerImages() {
				const { swiperIds } = config[this.scenicSpot];
				const promises = swiperIds.map(id => getArticleDetail({ Id: id }));
				try {
					this.bannerImages = [];
					const results = await Promise.all(promises);
					results.forEach(res => {
						if (res.Data?.CoverImg) {
							this.bannerImages.push({
								image: res.Data.CoverImg,
								title: res.Data.Title,
								id: res.Data.Id,
							});
						}
					})
					if (this.bannerImages.length) this.bannerTitle = this.bannerImages[0].title;
				} catch (error) {
					console.error('获取景区轮播图失败', error);
				}
			},

			// 轮播图切换
			bannerChange(index) {
				if (this.bannerImages[index]) {
					this.bannerTitle = this.bannerImages[index].title;
				}
			},

			// 监听滚动
			onScroll(e) {
				this.scrollTop = e.detail.scrollTop;
				this.showBackToTop = this.scrollTop > 300;

				// 判断是否应该移除nav-tabs的圆角
				if (this.scrollTop > 420) {
					this.isNavSticky = true;
				} else {
					this.isNavSticky = false;
				}

				// 更新当前导航状态
				this.updateCurrentTabByScroll();
			},

			// 根据滚动位置更新当前选中的标签
			updateCurrentTabByScroll() {
				// 获取各模块的位置信息
				const query = uni.createSelectorQuery();

				for (const key in this.module) {
					query.select(`#${this.module[key].id}`).boundingClientRect();
				}

				query.exec(res => {
					if (!res || !res.length) return;

					// 找到当前在可视区域内或接近顶部的模块
					const headerHeight = 100; // 导航栏高度估算值，可根据实际调整
					let activeTab = this.currentTab;

					for (let i = 0; i < res.length; i++) {
						const el = res[i];
						if (!el) continue;

						// 当元素顶部接近或已经进入导航栏下方时选中对应标签
						if (el.top <= headerHeight + 50 && el.bottom > headerHeight) {
							activeTab = Object.keys(this.module)[i];
							break;
						}
					}

					// 更新选中标签
					if (activeTab !== this.currentTab) {
						this.currentTab = activeTab;
					}
				});
			},

			// 点击导航锚点
			navigateToSection(sectionId) {
				this.currentTab = sectionId;
				this.scrollIntoView = sectionId;
			},

			// 获取商家
			async getTheMerchant(params) {
				return getShopBgList({
					...params,
					FiledOrder: 'Sort desc',
				});
			},

			// 获取文章
			async getTheArticle() {
				return useArticleApi({
					ArticleCategoryId: this.scenicSpot
				});
			},

			//获取推荐产品
			async getRecommendedProducts() {
				return getGoodsList({
					BusinessAreaId: this.regionalId,
					IsRecommend: 1
				});
			},

			// 跳转到详情页
			goToDetail(item, type) {
				let url = '';
				console.log(JSON.parse(JSON.stringify(item)), type)
				switch (type) {
					case 'attractions':
						url = `/mall_subpages/merchants/detail?id=${item.Id}&type=${item.BusinessClassify}`;
						break;
					case 'gourmet':
						url = `/mall_subpages/merchants/detail?id=${item.Id}&type=${item.BusinessClassify}`;
						break;
					case 'accommodation':
						url = `/mall_subpages/merchants/detail?id=${item.Id}&type=${item.BusinessClassify}`;
						break;
					case 'products':
						url = `/mall_subpages/goods-detail/goods-detail?id=${item.Id}`;
						break;
				}

				if (url) {
					uni.navigateTo({
						url
					});
				}
			},

			// 分享
			onShare() {
				// 分享逻辑
				uni.showToast({
					title: '分享功能开发中',
					icon: 'none'
				});
			},

			// 回到顶部
			scrollToTop() {
				// 先将scrollIntoView设置为空，后通过触发此字段的修改回到顶部
				this.scrollIntoView = '';
				this.$nextTick(() => {
					// 直接跳过scroll-view的约束，使用uni的API实现回到顶部
					uni.pageScrollTo({
						scrollTop: 0,
						duration: 300
					});
					// 同时设置scroll-top和scroll-into-view作为备选方案
					this.scrollTopValue = 0;
					this.scrollIntoView = this.topElementId;
				})
			}
		}
	}
</script>

<template>
	<scroll-view ref="scrollView" class="scroll-container" scroll-y :scroll-into-view="scrollIntoView"
		:scroll-with-animation="true" :scroll-top="scrollTopValue" @scroll="onScroll">
		<view :id="topElementId"></view>
		<view class="container" v-if="!pageLoading">
			<!-- 轮播图 -->
			<view class="carousel-section">
				<u-swiper :list="bannerImages" keyName="image" height="450rpx" :autoplay="true" :interval="5000"
					@change="bannerChange" indicator indicatorMode="dot" indicatorStyle="bottom: 70rpx"></u-swiper>
			</view>

			<!-- 景区基本信息 -->
			<view class="content">
				<!-- 导航锚点 -->
				<view class="nav-tabs" :class="{'sticky-active': isNavSticky}">
					<view v-for="(item, key) in module" :key="key" class="nav-tab"
						:class="{ active: currentTab === key }" @click="navigateToSection(key)">
						<text>{{ item.title }}</text>
					</view>
				</view>

				<!-- <view class="header">
          <view class="header-inner">
            <view class="title-wrap">
              <text class="title">{{ basicInfo.name || '景区名称' }}</text>
            </view>
            <view class="tag-list">
              <text class="tag">景点门票</text>
              <text class="tag">热门景点</text>
              <text class="tag">亲子游玩</text>
            </view>
            <view class="address-info">
              <view class="address-icon">
                <image src="https://wzws.wanshanlundiao.cn/upload/img/20250407/202504071011558093.png" mode="aspectFit"></image>
              </view>
              <view class="address-content">
                <text class="address-text">{{ basicInfo.address || '地处珠江口东南部，东邻香港，西接澳门' }}</text>
                <text class="business-time">营业时间 {{ basicInfo.businessHours || '13:30-21:00 (节假日提前至10:00)' }}</text>
              </view>
            </view>
          </view>
          <view class="share-btn">
            <image src="https://wzws.wanshanlundiao.cn/upload/img/20250407/202504071011497781.png" mode="aspectFit"></image>
            <button open-type="share">分享</button>
          </view>
        </view> -->

				<!-- 模块内容 -->
				<view class="modules-container">
					<!-- 乘船指南模块 -->
					<view class="module-section" :id="module.boatGuide.id">
						<view class="module-title">
							<text>{{ module.boatGuide.title }}</text>
						</view>

						<view class="module-content">
							<view class="skeleton-html" v-if="module.boatGuide.loading"></view>
							<mp-html
								:content="module.boatGuide.data && module.boatGuide.data.ChineseSubstance || '暂无内容'"
								></mp-html>
						</view>
					</view>

					<!-- 热门景点模块 -->
					<view class="module-section" :id="module.attractions.id">
						<view class="module-title">
							<text>{{ module.attractions.title }}</text>
						</view>
						<mp-html class="mb40" v-if="articleDetail.ChineseSubstance"
							:content="articleDetail.ChineseSubstance"></mp-html>
						<view class="module-content">
							<view class="skeleton-list" v-if="module.attractions.loading">
								<view class="skeleton-card" v-for="i in 3" :key="i"></view>
							</view>

							<view class="merchant-list" v-else>
								<view class="shop-container" v-for="(item, index) in module.attractions.data"
									:key="item.Id" :style="{'--item-index': index}"
									@click="goToDetail(item, 'attractions')" hover-class="shop-hover">
									<view class="shop-image">
										<image :src="item.ShopLogo" mode="aspectFill"></image>
										<view class="shop-tag" v-if="item.IsHot === 1">推荐</view>
										<view class="scenic-grade" v-if="item.SpotGrade">{{item.SpotGrade}}A级景区</view>
									</view>
									<view class="shop-info">
										<view class="shop-header">
											<text class="shop-name">{{ item.ShopName }}</text>
											<view class="shop-rating">
												<text class="rating-score">{{item.Score || 4.8}}</text>
												<text class="rating-text">分</text>
											</view>
										</view>
										<view class="shop-h">
											<view class="shop-tags">
												<text class="tag"
													v-for="(tag, tagIndex) in (item.Tags ? item.Tags.split(',') : [])"
													:key="tagIndex">{{tag}}</text>
											</view>
											<view class="shop-price" v-if="item.PerConsumption">
												<text class="price-value">¥{{item.PerConsumption}}</text>
												<text class="price-unit">/人起</text>
											</view>
										</view>
										<view class="shop-address" v-if="item.Address">
											<text class="address-icon">地址：</text>
											<text class="address-text">{{item.Address}}</text>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>

					<!-- 必打卡美食模块 -->
					<view class="module-section" :id="module.gourmet.id">
						<view class="module-title">
							<text>{{ module.gourmet.title }}</text>
						</view>
						<mp-html class="mb40" v-if="restaurantDetail.ChineseSubstance"
							:content="restaurantDetail.ChineseSubstance"></mp-html>
						<view class="module-content">
							<view class="skeleton-list" v-if="module.gourmet.loading">
								<view class="skeleton-card" v-for="i in 3" :key="i"></view>
							</view>

							<view class="merchant-list" v-else>
								<view class="gourmet-container" v-for="(item, index) in module.gourmet.data"
									:key="item.Id" :style="{'--item-index': index}" @click="goToDetail(item, 'gourmet')"
									hover-class="gourmet-hover">
									<view class="gourmet-image">
										<image :src="item.ShopLogo" mode="aspectFill"></image>
										<view class="shop-tag" v-if="item.IsRecommend">推荐</view>
									</view>
									<view class="gourmet-info">
										<view class="gourmet-info-top">
											<view class="gourmet-name-wrap">
												<text class="gourmet-name">{{item.ShopName}}</text>
												<view class="gourmet-rating">
													<text class="rating-score">{{item.Score || 4.8}}</text>
													<text class="rating-text">分</text>
												</view>
												<text class="shop-status" :class="{'shop-open': true}">营业中</text>
											</view>
											<view class="gourmet-time">营业时间：{{item.BusinessHours || '未设置营业时间'}}</view>
											<view class="gourmet-price">人均：<text
													class="price">¥{{item.PerConsumption || '--'}}</text></view>
											<view class="gourmet-tags">
												<text class="tag"
													v-for="(tag, tagIndex) in (item.Tags ? item.Tags.split(',').slice(0, 3) : [])"
													:key="tagIndex">{{tag}}</text>
												<text class="more-tags"
													v-if="item.Tags && item.Tags.split(',').length > 3">+{{item.Tags.split(',').length - 3}}</text>
											</view>
										</view>
										<view class="gourmet-bottom">
											<view class="gourmet-address">
												<text class="address-icon">地址：</text>
												<text class="address-text">{{item.Address}}</text>
											</view>
											<view class="gourmet-distance" v-if="item.Distance">
												<text>{{item.Distance}}km</text>
											</view>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>

					<!-- 岛上住宿模块 -->
					<view class="module-section" :id="module.accommodation.id">
						<view class="module-title">
							<text>{{ module.accommodation.title }}</text>
						</view>
						<mp-html class="mb40" v-if="hotelDetail.ChineseSubstance"
							:content="hotelDetail.ChineseSubstance" ></mp-html>
						<view class="module-content">
							<view class="skeleton-list" v-if="module.accommodation.loading">
								<view class="skeleton-card" v-for="i in 3" :key="i"></view>
							</view>

							<view class="merchant-list" v-else>
								<view class="hotel-container" v-for="(item, index) in module.accommodation.data"
									:key="item.Id" :style="{'--item-index': index}"
									@click="goToDetail(item, 'accommodation')" hover-class="hotel-hover">
									<view class="hotel-image">
										<image :src="item.ShopLogo" mode="aspectFill"></image>
										<view class="shop-tag" v-if="item.IsRecommend">推荐</view>
									</view>
									<view class="hotel-info">
										<view class="hotel-header">
											<text class="hotel-name">{{ item.ShopName }}</text>
											<text class="hotel-star" v-if="item.HotelStars">{{item.HotelStars}}星级</text>
											<view class="hotel-rating">
												<text class="rating-score">{{item.Score || 4.8}}</text>
												<text class="rating-text">分</text>
											</view>
										</view>
										<view class="hotel-h">
											<view class="hotel-tags">
												<text class="tag"
													v-for="(tag, tagIndex) in (item.Tags ? item.Tags.split(',') : [])"
													:key="tagIndex">{{tag}}</text>
											</view>
											<view class="hotel-price" v-if="item.PerConsumption">
												<text class="price-value">¥{{item.PerConsumption}}</text>
												<text class="price-unit">/晚起</text>
											</view>
										</view>
										<view class="hotel-address" v-if="item.Address">
											<text class="address-icon">地址：</text>
											<text class="address-text">{{item.Address}}</text>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>

					<!-- 推荐产品模块 -->
				<!-- 	<view class="module-section" :id="module.products.id">
						<view class="module-title">
							<text>{{ module.products.title }}</text>
						</view>

						<view class="module-content">
							<view class="skeleton-list" v-if="module.products.loading">
								<view class="skeleton-card" v-for="i in 3" :key="i"></view>
							</view>

							<view class="product-list" v-else>
								<view class="product-card" v-for="(item, index) in module.products.data" :key="item.Id"
									:style="{'--item-index': index}" @click="goToDetail(item, 'products')">
									<image class="product-image" :src="item.ImgUrl || item.Img || item.ImageUrl"
										mode="aspectFill"></image>
									<view class="product-info">
										<view class="product-name">{{ item.Name || item.ProductName }}</view>
										<view class="product-price">¥{{ item.Price || item.SalePrice || 0 }}</view>
									</view>
								</view>
							</view>
						</view>
					</view> -->
				</view>

				<HzSafeArea></HzSafeArea>
			</view>
		</view>

		<!-- 页面加载骨架屏 -->
		<view class="page-skeleton" v-if="pageLoading">
			<view class="skeleton-banner"></view>
			<view class="skeleton-info">
				<view class="skeleton-name"></view>
				<view class="skeleton-address"></view>
				<view class="skeleton-business"></view>
			</view>
			<view class="skeleton-tabs"></view>
			<view class="skeleton-module" v-for="i in 3" :key="i">
				<view class="skeleton-module-title"></view>
				<view class="skeleton-module-content"></view>
			</view>
		</view>

		<!-- 回到顶部按钮 -->
		<view class="back-to-top" v-if="showBackToTop" @click="scrollToTop">
			<image src="https://wzws.wanshanlundiao.cn/upload/img/20250414/202504141716291147.jpeg" mode="aspectFit">
			</image>
		</view>
	</scroll-view>
</template>

<style scoped lang="scss">
	.scroll-container {
		height: 100vh;
		background-color: #F5F7FA;
	}

	.container {
		min-height: 100vh;
	}

	/* 轮播图样式 */
	.carousel-section {
		position: relative;
		height: 450rpx;
	}

	/* 主体内容 */
	.content {
		margin-top: -40rpx;
		border-radius: 50rpx 50rpx 0 0;
		background-color: #F5F6F7;
		position: relative;
		z-index: 1;
		min-height: calc(100vh - 420rpx);
	}

	/* 头部信息 */
	.header {
		display: flex;
		padding: 30rpx;
		background-color: #fff;

		.header-inner {
			flex: 1;
		}

		.title-wrap {
			display: flex;
			justify-content: space-between;
			align-items: flex-start;
			margin-bottom: 15rpx;

			.title {
				font-size: 36rpx;
				font-weight: 600;
				color: #333;
				flex: 1;
			}
		}

		.share-btn {
			flex-shrink: 0;
			display: flex;
			flex-direction: column;
			align-items: center;
			margin-left: 15rpx;

			image {
				width: 36rpx;
				height: 36rpx;
			}

			button {
				background: none;
				border: none;
				padding: 0;
				font-size: 24rpx;
				color: #666;
				line-height: 1.2;
				margin-top: 4rpx;

				&::after {
					display: none;
				}
			}
		}

		.tag-list {
			display: flex;
			flex-wrap: wrap;
			gap: 16rpx;

			.tag {
				font-size: 24rpx;
				color: #666;
				background: #f5f5f5;
				padding: 6rpx 20rpx;
				border-radius: 24rpx;
			}
		}
	}

	.address-info {
		display: flex;
		padding: 15rpx 0;

		.address-icon {
			width: 21rpx;
			height: 25rpx;
			margin-right: 16rpx;
			display: flex;
			align-items: flex-start;
			padding-top: 6rpx;

			image {
				width: 30rpx;
				height: 30rpx;
			}
		}

		.address-content {
			flex: 1;
			display: flex;
			flex-direction: column;
			gap: 10rpx;

			.address-text {
				font-size: 24rpx;
				color: #333;
			}

			.business-time {
				font-size: 24rpx;
				color: #999;
			}
		}
	}

	.action-btns {
		display: flex;
		gap: 20rpx;
		padding: 30rpx;

		.btn {
			flex: 1;
			height: 80rpx;
			background: #fff;
			border-radius: 40rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			gap: 6rpx;

			image {
				width: 28rpx;
				height: 28rpx;
				margin-right: 5rpx;
			}

			text {
				font-size: 24rpx;
				color: #333;
			}
		}
	}

	/* 导航锚点 */
	.nav-tabs {
		position: sticky;
		top: 0;
		z-index: 10;
		display: flex;
		background-color: #fff;
		border-bottom: 1rpx solid #f0f0f0;
		overflow-x: auto;
		white-space: nowrap;
		padding: 0 20rpx;
		border-radius: 50rpx 50rpx 0 0;
		transition: border-radius 0.3s;

		&.sticky-active {
			border-radius: 0;
		}

		.nav-tab {
			padding: 20rpx 24rpx;
			font-size: 24rpx;
			color: #666;
			position: relative;
			flex-shrink: 0;

			&.active {
				color: #0087ff;
				font-weight: bold;

				&::after {
					content: '';
					position: absolute;
					bottom: 0;
					left: 24rpx;
					right: 24rpx;
					height: 4rpx;
					background-color: #0087ff;
					border-radius: 2rpx;
				}
			}
		}
	}

	/* 模块容器 */
	.modules-container {
		padding: 20rpx;
	}

	/* 模块通用样式 */
	.module-section {
		margin-bottom: 30rpx;
		background-color: #fff;
		border-radius: 16rpx;
		overflow: hidden;
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);

		.module-title {
			padding: 24rpx;
			font-size: 32rpx;
			font-weight: bold;
			color: #333;
			border-bottom: 1rpx solid #f5f5f5;
		}

		.module-content {
			padding: 20rpx;
		}

	}

	/* 商家卡片列表 */
	.merchant-list,
	.product-list {
		display: flex;
		flex-direction: column;
		gap: 20rpx;
	}

	/* 景点卡片样式 */
	.shop-container {
		background: #fff;
		border-radius: 16rpx;
		overflow: hidden;
		display: flex;
		flex-direction: column;
		margin-bottom: 20rpx;
		box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
		transition: all 0.2s ease;
		will-change: transform, opacity;
		opacity: 0;
		transform: translateY(30rpx);
		animation: fadeInUp 0.5s ease forwards;
		animation-delay: calc(0.1s * var(--item-index, 0));

		&.shop-hover {
			transform: scale(0.98);
			box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.02);
		}

		.shop-image {
			width: 100%;
			height: 320rpx;
			position: relative;
			flex-shrink: 0;

			image {
				width: 100%;
				height: 100%;
				object-fit: cover;
			}

			.shop-tag {
				position: absolute;
				top: 16rpx;
				left: 16rpx;
				background: linear-gradient(135deg, #ff6b6b, #ff8787);
				color: #fff;
				font-size: 22rpx;
				padding: 4rpx 12rpx;
				border-radius: 4rpx;
			}

			.scenic-grade {
				position: absolute;
				bottom: 16rpx;
				right: 16rpx;
				background: linear-gradient(135deg, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.8));
				color: #fff;
				font-size: 24rpx;
				padding: 6rpx 16rpx;
				border-radius: 6rpx;
				backdrop-filter: blur(4px);
			}
		}

		.shop-info {
			padding: 16rpx;

			.shop-header {
				display: flex;
				align-items: center;
				margin-bottom: 8rpx;

				.shop-name {
					font-size: 30rpx;
					font-weight: 600;
					color: #333;
					margin-right: 12rpx;
					flex: 1;
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}

				.shop-rating {
					display: flex;
					align-items: center;

					.rating-score {
						color: #ff6b6b;
						font-size: 26rpx;
						font-weight: 600;
						margin-right: 4rpx;
					}

					.rating-text {
						color: #ff6b6b;
						font-size: 20rpx;
					}
				}
			}

			.shop-h {
				display: flex;
				justify-content: space-between;
				margin-bottom: 8rpx;
				min-height: 34rpx;

				.shop-tags {
					flex: 1;
					display: flex;
					flex-wrap: wrap;
					gap: 8rpx;
					align-items: center;
					margin-right: 20rpx;
					min-width: 0;

					.tag {
						height: 34rpx;
						font-size: 20rpx;
						color: #36b365;
						background-color: rgba(54, 179, 101, 0.1);
						padding: 2rpx 8rpx;
						border-radius: 4rpx;
					}
				}

				.shop-price {
					font-size: 20rpx;
					color: #666;
					flex-shrink: 0;

					.price-value {
						font-size: 32rpx;
						font-weight: 600;
						color: #ff6b6b;
					}

					.price-unit {
						margin-left: 4rpx;
					}
				}
			}

			.shop-address {
				display: flex;
				align-items: flex-start;
				font-size: 20rpx;
				color: #999;

				.address-icon {
					flex-shrink: 0;
					margin-right: 4rpx;
				}

				.address-text {
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}
			}
		}
	}

	/* 美食卡片样式 */
	.gourmet-container {
		background: #fff;
		border-radius: 16rpx;
		overflow: hidden;
		display: flex;
		margin-bottom: 20rpx;
		padding: 24rpx;
		box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
		transition: all 0.2s ease;
		will-change: transform, opacity;
		opacity: 0;
		transform: translateY(30rpx);
		animation: fadeInUp 0.5s ease forwards;
		animation-delay: calc(0.1s * var(--item-index, 0));

		&.gourmet-hover {
			transform: scale(0.98);
			box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.02);
		}

		.gourmet-image {
			width: 180rpx;
			height: 180rpx;
			position: relative;
			flex-shrink: 0;
			margin-right: 24rpx;

			image {
				width: 100%;
				height: 100%;
				border-radius: 12rpx;
				object-fit: cover;
			}

			.shop-tag {
				position: absolute;
				top: 8rpx;
				left: 8rpx;
				background: linear-gradient(135deg, #ff6b6b, #ff8787);
				color: #fff;
				font-size: 20rpx;
				padding: 2rpx 10rpx;
				border-radius: 4rpx;
			}
		}

		.gourmet-info {
			flex: 1;
			display: flex;
			flex-direction: column;
			justify-content: space-between;
			overflow: hidden;
			min-height: 180rpx;
			max-height: 180rpx;

			.gourmet-info-top {
				flex: 1;
				display: flex;
				flex-direction: column;
				overflow: hidden;

				.gourmet-name-wrap {
					display: flex;
					align-items: center;
					margin-bottom: 6rpx;

					.gourmet-name {
						font-size: 30rpx;
						font-weight: 600;
						color: #333;
						margin-right: 12rpx;
						max-width: 65%;
						overflow: hidden;
						text-overflow: ellipsis;
						white-space: nowrap;
					}

					.gourmet-rating {
						display: flex;
						align-items: center;
						margin-right: auto;

						.rating-score {
							color: #ff6b6b;
							font-size: 28rpx;
							font-weight: 600;
							margin-right: 4rpx;
						}

						.rating-text {
							color: #ff6b6b;
							font-size: 22rpx;
							margin-right: 12rpx;
						}
					}

					.shop-status {
						font-size: 20rpx;
						padding: 2rpx 8rpx;
						border-radius: 4rpx;
						background: #f5f5f5;
						color: #999;
						flex-shrink: 0;

						&.shop-open {
							background: rgba(#67c23a, 0.1);
							color: #67c23a;
						}
					}
				}

				.gourmet-time {
					font-size: 22rpx;
					color: #666;
					margin-bottom: 4rpx;
					white-space: nowrap;
					overflow: hidden;
					text-overflow: ellipsis;
				}

				.gourmet-price {
					font-size: 22rpx;
					color: #666;
					margin-top: 4rpx;

					.price {
						color: #ff6b6b;
						font-weight: 600;
					}
				}

				.gourmet-tags {
					display: flex;
					flex-wrap: nowrap;
					gap: 8rpx;
					margin-top: 6rpx;
					overflow: hidden;
					white-space: nowrap;

					.tag {
						display: inline-block;
						font-size: 20rpx;
						color: #498FFF;
						background-color: rgba(73, 143, 255, 0.1);
						padding: 2rpx 10rpx;
						border-radius: 6rpx;
						max-width: 120rpx;
						overflow: hidden;
						text-overflow: ellipsis;
					}

					.more-tags {
						font-size: 20rpx;
						color: #999;
					}
				}
			}

			.gourmet-bottom {
				display: flex;
				justify-content: space-between;
				align-items: center;
				margin-top: 6rpx;
				white-space: nowrap;

				.gourmet-address {
					flex: 1;
					display: flex;
					align-items: center;
					font-size: 20rpx;
					color: #999;
					margin-right: 12rpx;
					overflow: hidden;

					.address-icon {
						flex-shrink: 0;
						margin-right: 6rpx;
					}

					.address-text {
						overflow: hidden;
						text-overflow: ellipsis;
						white-space: nowrap;
					}
				}

				.gourmet-distance {
					font-size: 20rpx;
					color: #999;
					flex-shrink: 0;
				}
			}
		}
	}

	/* 酒店卡片样式 */
	.hotel-container {
		background: #fff;
		border-radius: 16rpx;
		overflow: hidden;
		display: flex;
		flex-direction: column;
		margin-bottom: 20rpx;
		box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
		transition: all 0.2s ease;
		will-change: transform, opacity;
		opacity: 0;
		transform: translateY(30rpx);
		animation: fadeInUp 0.5s ease forwards;
		animation-delay: calc(0.1s * var(--item-index, 0));

		&.hotel-hover {
			transform: scale(0.98);
			box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.02);
		}

		.hotel-image {
			width: 100%;
			height: 300rpx;
			position: relative;
			flex-shrink: 0;

			image {
				width: 100%;
				height: 100%;
				object-fit: cover;
			}

			.shop-tag {
				position: absolute;
				top: 16rpx;
				left: 16rpx;
				background: linear-gradient(135deg, #ff6b6b, #ff8787);
				color: #fff;
				font-size: 22rpx;
				padding: 4rpx 12rpx;
				border-radius: 4rpx;
			}
		}

		.hotel-info {
			padding: 16rpx;

			.hotel-header {
				display: flex;
				align-items: center;
				margin-bottom: 8rpx;

				.hotel-name {
					font-size: 30rpx;
					font-weight: 600;
					color: #333;
					margin-right: 12rpx;
					max-width: 45%;
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}

				.hotel-star {
					font-size: 20rpx;
					color: #ffa41c;
					background-color: rgba(255, 164, 28, 0.1);
					padding: 2rpx 8rpx;
					border-radius: 4rpx;
					margin-right: auto;
				}

				.hotel-rating {
					display: flex;
					align-items: center;

					.rating-score {
						color: #ff6b6b;
						font-size: 26rpx;
						font-weight: 600;
						margin-right: 4rpx;
					}

					.rating-text {
						color: #ff6b6b;
						font-size: 20rpx;
					}
				}
			}

			.hotel-h {
				display: flex;
				justify-content: space-between;
				margin-bottom: 8rpx;
				min-height: 34rpx;

				.hotel-tags {
					flex: 1;
					display: flex;
					flex-wrap: wrap;
					gap: 8rpx;
					align-items: center;
					margin-right: 20rpx;
					min-width: 0;

					.tag {
						height: 34rpx;
						font-size: 20rpx;
						color: #498fff;
						background-color: rgba(73, 143, 255, 0.1);
						padding: 2rpx 8rpx;
						border-radius: 4rpx;
					}
				}

				.hotel-price {
					font-size: 20rpx;
					color: #666;
					flex-shrink: 0;

					.price-value {
						font-size: 32rpx;
						font-weight: 600;
						color: #ff6b6b;
					}

					.price-unit {
						margin-left: 4rpx;
					}
				}
			}

			.hotel-address {
				display: flex;
				align-items: flex-start;
				font-size: 20rpx;
				color: #999;

				.address-icon {
					flex-shrink: 0;
					margin-right: 4rpx;
				}

				.address-text {
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}
			}
		}
	}

	/* 产品卡片列表 */
	.product-list {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		justify-content: space-between;
	}

	.product-card {
		width: calc(50% - 16rpx);
		background-color: #fff;
		border-radius: 12rpx;
		overflow: hidden;
		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
		transform: translateY(30rpx);
		opacity: 0;
		animation: fadeInUp 0.5s ease forwards;
		animation-delay: calc(0.1s * var(--item-index, 0));

		.product-image {
			width: 100%;
			height: 240rpx;
			object-fit: cover;
		}

		.product-info {
			padding: 16rpx;

			.product-name {
				font-size: 28rpx;
				color: #333;
				margin-bottom: 10rpx;
				white-space: nowrap;
				overflow: hidden;
				text-overflow: ellipsis;
			}

			.product-price {
				font-size: 32rpx;
				color: #FF5722;
				font-weight: bold;
			}
		}
	}

	/* 骨架屏样式 */
	.skeleton-list {
		display: flex;
		flex-direction: column;
		gap: 20rpx;
	}

	.skeleton-card {
		height: 180rpx;
		background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
		background-size: 400% 100%;
		animation: shimmer 1.5s infinite;
		border-radius: 12rpx;
	}

	.skeleton-html {
		height: 400rpx;
		background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
		background-size: 400% 100%;
		animation: shimmer 1.5s infinite;
		border-radius: 12rpx;
	}

	/* 整页骨架屏 */
	.page-skeleton {
		padding: 20rpx;

		.skeleton-banner {
			height: 480rpx;
			background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
			background-size: 400% 100%;
			animation: shimmer 1.5s infinite;
			margin-bottom: 30rpx;
		}

		.skeleton-info {
			padding: 20rpx;
			background-color: #fff;
			border-radius: 16rpx;
			margin-bottom: 20rpx;

			.skeleton-name {
				height: 40rpx;
				width: 50%;
				background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
				background-size: 400% 100%;
				animation: shimmer 1.5s infinite;
				margin-bottom: 16rpx;
			}

			.skeleton-address,
			.skeleton-business {
				height: 30rpx;
				width: 80%;
				background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
				background-size: 400% 100%;
				animation: shimmer 1.5s infinite;
				margin-bottom: 10rpx;
			}
		}

		.skeleton-tabs {
			height: 80rpx;
			background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
			background-size: 400% 100%;
			animation: shimmer 1.5s infinite;
			margin-bottom: 30rpx;
		}

		.skeleton-module {
			margin-bottom: 30rpx;

			.skeleton-module-title {
				height: 40rpx;
				width: 30%;
				background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
				background-size: 400% 100%;
				animation: shimmer 1.5s infinite;
				margin-bottom: 20rpx;
			}

			.skeleton-module-content {
				height: 300rpx;
				background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
				background-size: 400% 100%;
				animation: shimmer 1.5s infinite;
			}
		}
	}

	/* 动画效果 */
	@keyframes fadeInUp {
		from {
			opacity: 0;
			transform: translateY(30rpx);
		}

		to {
			opacity: 1;
			transform: translateY(0);
		}
	}

	@keyframes shimmer {
		0% {
			background-position: 100% 0;
		}

		100% {
			background-position: -100% 0;
		}
	}

	/* 回到顶部按钮 */
	.back-to-top {
		position: fixed;
		right: 30rpx;
		bottom: 120rpx;
		width: 80rpx;
		height: 80rpx;
		background: rgba(255, 255, 255, 0.9);
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
		z-index: 99;
		transition: all 0.3s ease;

		image {
			width: 40rpx;
			height: 40rpx;
		}

		&:active {
			transform: scale(0.95);
		}
	}
</style>